package com.jack006.stock.service.impl;

import com.jack006.exception.GraceException;
import com.jack006.grace.result.ResponseStatusEnum;
import com.jack006.pojo.StockDayDetail;
import com.jack006.pojo.StockInfo;
import com.jack006.pojo.StockNowDetail;
import com.jack006.pojo.bo.StockChangeBO;
import com.jack006.pojo.bo.StockFlushBO;
import com.jack006.stock.mapper.StockDayDetailMapper;
import com.jack006.stock.mapper.StockInfoMapper;
import com.jack006.stock.mapper.StockNowDetailMapper;
import com.jack006.stock.service.StockService;
import com.jack006.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * @Classname StockServiceImpl
 * @Description 股票服务实现
 * @Date 2021-07-18 10:33
 * @Created by jack
 */
@Service
public class StockServiceImpl implements StockService {

    final static Logger logger = LoggerFactory.getLogger(StockServiceImpl.class);

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private StockInfoMapper stockInfoMapper;
    @Autowired
    private StockNowDetailMapper stockNowDetailMapper;
    @Autowired
    private StockDayDetailMapper stockDayDetailMapper;
    @Autowired
    private Sid sid;


    @Override
    public void recordFlushInfo(String code) {
        saveNowDetail(code);
    }


    @Transactional
    public void saveNowDetail(String code) {
        StockFlushBO stockFlushBO = parseSinaData(code);
        if (stockFlushBO != null) {
            StockNowDetail nowDetail = new StockNowDetail();
            String primaryId = sid.nextShort();
            nowDetail.setId(primaryId);
            nowDetail.setName(stockFlushBO.getName());
            nowDetail.setCode(code);
            nowDetail.setDelFlag(1);
            nowDetail.setNowPrice(new BigDecimal(stockFlushBO.getNowPrice()));
            nowDetail.setNowVolume(Integer.parseInt(stockFlushBO.getFinishVolume()));
            nowDetail.setNowHighPrice(new BigDecimal(stockFlushBO.getNowHighPrice()));
            nowDetail.setNowLowPrice(new BigDecimal(stockFlushBO.getNowLowPrice()));
            nowDetail.setOpenPrice(new BigDecimal(stockFlushBO.getNowOpenPrice()));
            nowDetail.setYesterdayPrice(new BigDecimal(stockFlushBO.getYesterDayClosePrice()));
            try {
                if (stockFlushBO.getNowTime() != null) {
                    nowDetail.setCreateTime(stockFlushBO.getNowTime());
                    int result = stockNowDetailMapper.insert(nowDetail);
                    if (result != 1) {
                        GraceException.display(ResponseStatusEnum.SYSTEM_OPERATION_ERROR);
                    }
                }else {
                    logger.error("没有找到当前时间的股票的数据");
                }
            }catch (Exception e) {
                logger.error(e.getMessage());
            }

        }
    }

    /**
     * 获取股票换手率信息
     * @param code
     * @return
     */
    public StockChangeBO getStockChange(String code) {
        String queryCode = null;
        if (code.startsWith("6")) {
            queryCode = "1."+code;
        }else if (code.startsWith("0")){
            queryCode = "0."+code;
        }
        String url = "https://appiiexternal3.eastmoney.com/corparation_list_stock/single?" +
                "cmd=6&cls=StockHolderList&stock="+queryCode;
        ResponseEntity<StockChangeBO> forEntity = restTemplate.getForEntity(url, StockChangeBO.class);
        StockChangeBO body = forEntity.getBody();
        return body;
    }

    @Transactional
    @Override
    public void createStock(String code) {
        StockInfo queryInfo = new StockInfo();
        queryInfo.setCode(code);
        StockInfo stockInfo = stockInfoMapper.selectOne(queryInfo);
        if (stockInfo == null) {
            StockInfo info = new StockInfo();
            if (code.startsWith("0")) {
                info.setStockTypeName("深A");
                info.setStockType("sz");
                info.setCode(code);
            } else if (code.startsWith("6")){
                info.setStockTypeName("沪A");
                info.setStockType("sh");
                info.setCode(code);
            }
            info.setCreateTime(new Date());
            info.setDelFlag(1);
            StockFlushBO flushVO = parseSinaData(code);
            info.setName(flushVO.getName());
            int result = stockInfoMapper.insert(info);
            if (result != 1) {
                GraceException.display(ResponseStatusEnum.SYSTEM_OPERATION_ERROR);
            }
        }else {
            GraceException.display(ResponseStatusEnum.STOCK_CODE_EXIST_ERROR);
        }
    }

    @Override
    public void recordStockNowDetail() {
        List<StockInfo> stockInfos = stockInfoMapper.selectAll();
        for (StockInfo stockInfo : stockInfos) {
            String code = stockInfo.getCode();
            recordFlushInfo(code);
        }
    }

    @Override
    public void recordStockDayDetail() {
        List<StockInfo> stockInfos = stockInfoMapper.selectAll();
        for (StockInfo stockInfo : stockInfos) {
            String code = stockInfo.getCode();
            saveDayDetail(code);
        }
    }

    @Override
    public void recordStockDayInfo(String code) {
        saveDayDetail(code);
    }


    @Transactional
    public void saveDayDetail(String code) {
        StockFlushBO stockFlushBO = parseSinaData(code);
        StockChangeBO stockChange = getStockChange(code);
        if (stockChange != null && stockChange != null) {
            String currentDateString = DateUtil.getCurrentDateString();
            String nowHighPrice = stockFlushBO.getNowHighPrice();
            // 差值0.2
            Double highPrice = new BigDecimal(nowHighPrice).subtract(new BigDecimal("0.1")).doubleValue();
            List<StockNowDetail> highDetailList = stockNowDetailMapper.getHighDayDetail(code,currentDateString,highPrice);
            if (highDetailList.isEmpty()) {
                return;
            }

            // 差值0.2
            String nowLowPrice = stockFlushBO.getNowLowPrice();
            Double lowPrice = new BigDecimal(nowLowPrice).add(new BigDecimal("0.1")).doubleValue();
            List<StockNowDetail> lowDetailList = stockNowDetailMapper.getLowDayDetail(code,currentDateString,lowPrice);
            if (lowDetailList.isEmpty()) {
                return;
            }

            StockDayDetail dayDetail = new StockDayDetail();
            String primaryId = sid.nextShort();
            dayDetail.setId(primaryId);
            dayDetail.setCode(code);
            dayDetail.setName(stockFlushBO.getName());
            dayDetail.setDelFlag(1);
            dayDetail.setCreateTime(new Date());
            String changeRatio = convertChangeRatio(stockChange.getChangeRatio());
            String diffMoney = convertDiffMoney(stockChange.getChange());
            dayDetail.setDiffMoney(new BigDecimal(diffMoney));
            dayDetail.setDayChangeRate(new BigDecimal(changeRatio));
            dayDetail.setDayFinishVolume(Integer.valueOf(stockFlushBO.getFinishVolume()));
            dayDetail.setDayTotalMoney(new BigDecimal(stockFlushBO.getFinishMoney()));
            dayDetail.setDayHighPrice(new BigDecimal(stockFlushBO.getNowHighPrice()));
            dayDetail.setDayLowPrice(new BigDecimal(stockFlushBO.getNowLowPrice()));

            Date highEndTime = highDetailList.get(0).getCreateTime();
            Date highStartTime = highDetailList.get(highDetailList.size()-1).getCreateTime();
            StringBuilder adviceBuilder = new StringBuilder();
            String highEndDateStr = DateUtil.dateToString(highEndTime, DateUtil.DATETIME_PATTERN);
            String highStartDateStr = DateUtil.dateToString(highStartTime, DateUtil.DATETIME_PATTERN);
            dayDetail.setBestTime(highEndTime);
            adviceBuilder.append("在"+highStartDateStr+"--"+highEndDateStr+"之间买入；");
            dayDetail.setDayHighPriceTime(highEndTime);

            Date lowEndTime = lowDetailList.get(lowDetailList.size()-1).getCreateTime();
            Date lowStartTime = lowDetailList.get(0).getCreateTime();
            String lowEndDateStr = DateUtil.dateToString(lowEndTime, DateUtil.DATETIME_PATTERN);
            String lowStartDateStr = DateUtil.dateToString(lowStartTime, DateUtil.DATETIME_PATTERN);
            adviceBuilder.append("在"+lowStartDateStr+"--"+lowEndDateStr+"之间卖出；");


            dayDetail.setDayLowPriceTime(lowEndTime);
            dayDetail.setOpenPrice(new BigDecimal(stockFlushBO.getNowOpenPrice()));
            dayDetail.setYesterdayPrice(new BigDecimal(stockFlushBO.getYesterDayClosePrice()));

            // 添加建议
            dayDetail.setAdvice(adviceBuilder.toString());

            stockDayDetailMapper.insert(dayDetail);
        }
    }

    private String convertDiffMoney(String diffMoney) {
        String diff = "0";
        if (diffMoney.startsWith("+")) {
            diff = StringUtils.substringAfterLast(diffMoney,"+");
        } else if (diffMoney.startsWith("-")) {
            diff = StringUtils.substringAfterLast(diffMoney,"-");
        }
        return diff;
    }

    private String convertChangeRatio(String changeRatio) {
        String ratio = "0";
        if (changeRatio.startsWith("+")) {
            ratio = StringUtils.substringBetween(changeRatio,"+","%");
        } else if (changeRatio.startsWith("-")) {
            ratio = StringUtils.substringBetween(changeRatio,"-","%");
        }
        return ratio;
    }


    /**
     * 获取新浪股票数据
     * @param code
     * @return
     */
    public StockFlushBO parseSinaData(String code) {
        String queryCode = null;
        if (code.startsWith("0")) {
            queryCode = "sz"+code;
        } else if (code.startsWith("6")){
            queryCode = "sh"+code;
        }
        String flushServerUrlExecute = "https://hq.sinajs.cn/list="+queryCode;
        ResponseEntity<String> responseEntity
                = restTemplate.getForEntity(flushServerUrlExecute, String.class);
        String body = responseEntity.getBody();
        StockFlushBO flushBO = null;
        if (StringUtils.isNotBlank(body)) {
            // logger.info(code+"在新浪返回接口数据==>"+body);
            String info = StringUtils.substringBetween(body, "=\"", "\"");
            String[] split = info.split(",");
            flushBO = new StockFlushBO();
            flushBO.setCode(code);
            flushBO.setName(split[0]);
            flushBO.setNowOpenPrice(split[1]);
            flushBO.setYesterDayClosePrice(split[2]);
            flushBO.setNowPrice(split[3]);
            flushBO.setNowHighPrice(split[4]);
            flushBO.setNowLowPrice(split[5]);
            flushBO.setPlanBuyPrice(split[6]);
            flushBO.setPlanSellPrice(split[7]);
            flushBO.setFinishVolume(split[8]);
            flushBO.setFinishMoney(split[9]);
            String dateStr = DateUtil.dateToString(new Date(), "yyyy-MM-dd");

            String nowTimeStr = StringUtils.substringBetween(body, dateStr+",", ",00");
            if (nowTimeStr != null) {
                Date nowDate = DateUtil.stringToDate(dateStr +" "+ nowTimeStr, DateUtil.DATETIME_PATTERN);
                flushBO.setNowTime(nowDate);
            }
        }
        return flushBO;
    }

    public static void main(String[] args) {
        String name = "var hq_str_sh605111=\"新洁能,155.680,157.150,150.440,159.180,150.440,150.430,150.440,4714337,727780979.000,200,150.430,500,150.420,600,150.400,200,150.390,300,150.380,63640,150.440,37560,150.450,1600,150.470,1300,150.480,1300,150.490,2021-07-16,15:00:01,00,\"";
        // String s = StringUtils.substringBetween(name, "=\"", ",\"");
//        String dateStr = DateUtil.dateToString(new Date(), "yyyy-MM-dd");
//        String s1 = StringUtils.substringBetween(name, "2021-07-16,", ",00,\"");
//        Date nowDate = DateUtil.stringToDate("2021-07-16" + s1, "yyyy-MM-ddHH:mm:ss");
//        System.out.println(s1);

        Timestamp currentTimestamp = DateUtil.getCurrentTimestamp();
        System.out.println(System.currentTimeMillis());
        Timestamp ts = new Timestamp(new Date().getTime());
         int t = (int) ((ts.getTime())/1000);
        System.out.println(t);
        System.out.println(System.currentTimeMillis()/1000);
    }
}
